package com.atguigu.lease.common.utils;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;

/**
 * JWT工具类，用于生成和解析JWT令牌
 */
public class JwtUtil {
    /**
     * JWT密钥，使用HS256算法生成
     */
    private static SecretKey secretKey = Keys.hmacShaKeyFor("rZ4ebMhxrbhrHJc66JR248FBDVpmpmR5".getBytes());

    /**
     * 创建JWT令牌
     * @param userId 用户ID
     * @param username 用户名
     * @return 生成的JWT令牌字符串
     */
    public static String createToken(Long userId, String username) {
        String jwt = Jwts.builder()
                // 设置过期时间为1小时后
                .setExpiration(new Date(System.currentTimeMillis() + 3600000))
                // 设置主题为"LOGIN"
                .setSubject("LOGIN")
                // 添加用户ID声明
                .claim("userId", userId)
                // 添加用户名声明
                .claim("username", username)
                // 使用HS256算法和密钥进行签名
                .signWith(secretKey, SignatureAlgorithm.HS256)
                // 生成紧凑的JWT字符串
                .compact();

        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param token JWT令牌字符串
     * @return 解析后的Claims对象，包含令牌中的所有声明
     * @throws LeaseException 当令牌为null、过期或无效时抛出
     */
    public static Claims parseToken(String token) {
        // 如果令牌为null，抛出认证异常
        if (token == null) {
            throw new LeaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);
        }
        try {
            // 使用密钥解析令牌
            Jws<Claims> jws = Jwts.parserBuilder()
                    .setSigningKey(secretKey)
                    .build()
                    .parseClaimsJws(token);
            return jws.getBody();
        } catch (ExpiredJwtException e) {
            // 令牌过期异常
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        } catch (JwtException e) {
            // 令牌无效异常
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }
    }

    /**
     * 测试方法，用于生成测试令牌
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 生成用户ID为2，用户名为"18193656517"的测试令牌
        System.out.println(createToken(2L, "18193656517"));
    }
}
